/*
 * Copyright (C) 2008-2011 University of Deusto
 * 
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 * 
 * This software consists of contributions made by many individuals, 
 * listed below:
 *
 * Author: Aitor Gómez Goiri <aitor.gomez@deusto.es>
 */

package otso.se.network.sockets.communication.resources.query;

import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.resource.ResourceException;

import otso.se.network.sockets.communication.abstraction.HttpRequest;
import otso.se.network.sockets.communication.abstraction.HttpRequest.Operation;
import otso.se.network.sockets.communication.abstraction.HttpResponse;
import otso.se.network.sockets.communication.abstraction.annotations.HttpHandler;
import otso.se.network.sockets.communication.abstraction.annotations.Path;
import otso.se.network.sockets.communication.resources.AbstractServerResource;
import otsopack.commons.IController;
import otsopack.commons.data.Graph;
import otsopack.commons.data.SemanticFormat;
import otsopack.commons.data.Template;
import otsopack.commons.exceptions.MalformedTemplateException;
import otsopack.commons.exceptions.SpaceNotExistsException;
import otsopack.commons.exceptions.UnsupportedSemanticFormatException;
import otsopack.commons.exceptions.UnsupportedTemplateException;
import otsopack.full.java.network.communication.resources.graphs.WildcardConverter;

//{object-uri} can be "*" also ( /{subject}/{predicate}/* )
@Path("/spaces/{space}/query/wildcards/{subject}/{predicate}/{object-uri}")
// add another! WildcardsGraphResource.ROOT + "/{subject}/{predicate}/{object-type}/{object-value}"
public class WildcardQueryResource extends AbstractServerResource {
	
	private Template getWildcard() {
		final String subject     = getArgument("subject");
		final String predicate   = getArgument("predicate");
		final String objectUri   = getArgument("object-uri");
		final String objectValue = getArgument("object-value");
		final String objectType  = getArgument("object-type");
		
		try {
			return WildcardConverter.createTemplateFromURL(subject, predicate, objectUri, objectValue, objectType, getOtsopackApplication().getPrefixesStorage());
		} catch (MalformedTemplateException e) {
			//TODO never thrown!
			throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
			//throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "Could not serialize retrieved data", e);
		} catch (Exception e) {
			//TODO is this a internal error or a bad request?
			throw new ResourceException(Status.SERVER_ERROR_INTERNAL, "The given prefix used in the template does not exist");
		}
	}
	
	protected Graph getTriplesByWildcard(SemanticFormat outputFormat) {
		final String space = getArgument("space");
		final Template tpl = getWildcard();
		final IController controller = getController();
		
		try {
			return controller.getDataAccessService().query(space,tpl, outputFormat);
		} catch (SpaceNotExistsException e) {
			throw new ResourceException(Status.CLIENT_ERROR_NOT_FOUND, SpaceNotExistsException.HTTPMSG);
		} catch (UnsupportedSemanticFormatException e) {
			throw new ResourceException(Status.CLIENT_ERROR_NOT_ACCEPTABLE, "Unsupported output format: " + outputFormat);
		} catch (UnsupportedTemplateException e) {
			throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
		}
	}
	
	@HttpHandler(Operation.GET)
	public HttpResponse query(HttpRequest request){
		//SemanticFormat semanticFormat = checkOutputSemanticFormats();
		final Graph graph = getTriplesByWildcard(SemanticFormat.NTRIPLES);
		final HttpResponse resp = new HttpResponse(Status.SUCCESS_OK, System.currentTimeMillis());
		resp.setContentType(MediaType.TEXT_RDF_NTRIPLES.getName());
		resp.setData( (graph==null)? "": graph.getData() );
		return resp;
	}
}